#include "grate_test_utils.h"
#include "grate/util/common.h"

using growth_rate::PhysicalMemory;
using growth_rate::Malloc;
using growth_rate::Free;
using growth_rate::AllocateArray;
using growth_rate::FreeArray;
using growth_rate::ReallocateArray;
using growth_rate::ScopedArray;
using growth_rate::AutoObjectDeleter;

namespace {

TEST(Common, MallocAndFree) {
  {
    char *arr = reinterpret_cast<char*>(Malloc(10));
    EXPECT_FALSE(NULL == arr);
    Free(arr);
  }
  {
    int *arr = AllocateArray<int>(10);
    EXPECT_FALSE(NULL == arr);
    arr[0] = 0;
    arr[4] = 4;
    ReallocateArray(&arr, 5);
    EXPECT_EQ(0, arr[0]);
    EXPECT_EQ(4, arr[4]);
    FreeArray(&arr);
    EXPECT_EQ(NULL, arr);
  }
}

TEST(Common, ArraySize) {
  int int_arr[] = {5, 6, 7};
  EXPECT_EQ(3U, ARRAYSIZE(int_arr));
  double double_arr[5] = { 1.0 };
  EXPECT_EQ(5U, ARRAYSIZE(double_arr));
}

TEST(Common, ScopedArray) {
  ScopedArray<int> int_arr(10);
  ScopedArray<double> double_arr;
  int_arr[0] = 42;
  int_arr[9] = 18;
  EXPECT_EQ(42, int_arr[0]);
  EXPECT_EQ(18, int_arr[9]);
  int_arr.clear();
  EXPECT_EQ(0, int_arr[0]);
  EXPECT_EQ(0, int_arr[9]);
  double_arr.initialize(10);
  double_arr[0] = 42.0;
  double_arr[9] = -42.0;
  EXPECT_EQ(42.0, double_arr[0]);
  EXPECT_EQ(-42.0, double_arr[9]);
}

TEST(Common, AutoObjectDeleter) {
  volatile int *x = new int;
  *x = 4;
  AutoObjectDeleter<volatile int> int_deleter(x);
}

TEST(Common, PhysicalMemory) {
  uint64_t mem = PhysicalMemory();
  EXPECT_GT(mem, 0);
  EXPECT_LT(mem, 1ULL << 37);
}

}  // namespace
